package com.mike.uaa.server.service.impl;

import com.mike.uaa.core.Authentication;
import com.mike.uaa.core.AuthenticationUtils;
import com.mike.uaa.core.User;
import com.mike.uaa.server.authentication.AuthenticationManager;
import com.mike.uaa.server.authentication.converter.AuthenticationConverter;
import com.mike.uaa.server.authentication.processors.AuthenticationPostProcessor;
import com.mike.uaa.server.authentication.strategy.AuthenticationStrategyManager;
import com.mike.uaa.server.domain.response.AuthenticationResponse;
import com.mike.uaa.server.service.AuthenticationService;
import com.mike.uaa.web.Exceptions;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

/**
 * @author z zhang
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AuthenticationServiceImpl implements AuthenticationService {

    private final AuthenticationManager authenticationManager;
    private final AuthenticationConverter authenticationConverter;
    private final AuthenticationStrategyManager authenticationStrategyManager;
    private final AuthenticationPostProcessor authenticationPostProcessor;

    @ResponseBody
    @Override
    public AuthenticationResponse login(HttpServletRequest request) {
        Authentication result;
        //转化请求认证对象
        Authentication authentication = authenticationConverter.convert(request);
        if (StringUtils.isEmpty(authentication)){
            log.info("没有支持的身份验证器");
            throw Exceptions.createIllegalAccessException("没有支持的身份验证器");
        }
        try {
            //认证
            Authentication authenticated = authenticationManager.authenticate(authentication);
            if (AuthenticationUtils.isAuthenticated(authenticated)) {
                //已认证的
                result = authenticationPostProcessor.process(authenticated);
            } else {
                result = authenticationStrategyManager.handle(authenticated, null);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result = authenticationStrategyManager.handle(authentication, e);
        }
        AuthenticationResponse response = new AuthenticationResponse();
        response.setAuthenticated(result.isAuthenticated());
        if (AuthenticationUtils.isAuthenticated(result)) {
            response.setTokenValue(result.getTokenValue());
            response.setUsername(((User) result.getPrincipal()).getNickname());
        } else {
            response.setError(result.getPrincipal().toString());
        }

        return response;
    }
}
